/******************************************************************
*
*	CyberHTTP for Java
*
*	Copyright (C) Satoshi Konno 2002
*
*	File: HTTP.java
*
*	Revision;
*
*	11/18/02
*		- first revision.
*	08/30/03
*		- Giordano Sassaroli <sassarol@cefriel.it>
*		- Problem : the method getPort should return the default http port 80 when a port is not specified
*		- Description : the method is used in ControlRequest.setRequestHost() and in SubscriptionRequest.setService(). maybe the default port check could be done in these methods.
*	09/03/02
*		- Added getRequestHostURL().
*	
******************************************************************/

package com.cidero.http;

import java.net.*;

public class HTTP 
{
  public static final String HOST = "HOST";
  public static final String VERSION = "1.1";
  public static final String CRLF = "\r\n";
  public static final String TAB = "\t";
  
  public static final String SOAP_ACTION = "SOAPACTION";

  public static final String M_SEARCH = "M-SEARCH";
  public static final String NOTIFY = "NOTIFY";
  public static final String POST = "POST";
  public static final String GET = "GET";
  public static final String HEAD = "HEAD";
  public static final String SUBSCRIBE = "SUBSCRIBE";
  public static final String UNSUBSCRIBE = "UNSUBSCRIBE";
  
  public static final String DATE = "DATE";
  public static final String CONTENT_TYPE = "CONTENT-TYPE";
  public static final String CONTENT_LENGTH = "CONTENT-LENGTH";
  public static final String CACHE_CONTROL = "CACHE-CONTROL";
  public static final String USER_AGENT = "USER-AGENT";
  public static final String SERVER = "SERVER";

  public static final String NO_CACHE = "no-cache";
  public static final String MAX_AGE = "max-age";
  
  public static final String ST = "ST";
  public static final String MX = "MX";
  public static final String MAN = "MAN";
  public static final String LOCATION = "LOCATION";
  public static final String NT = "NT";
  public static final String NTS = "NTS";
  public static final String USN = "USN";
  public static final String EXT = "EXT";
  public static final String SID = "SID";
  public static final String SEQ = "SEQ";
  public final static String CALLBACK = "CALLBACK";
  public final static String TIMEOUT = "TIMEOUT";

  public static final String REQEST_LINE_DELIM = " ";
  public static final String HEADER_LINE_DELIM = " :";
  public static final String STATUS_LINE_DELIM = " ";

  public static final int DEFAULT_PORT = 80;
  
  /**
   * Check if a URL is absolute (contains http:host<:port>/path, with
   * port field being optional)
   *
   * @return  true if URL is absolute, otherwise false
   */
  public static final boolean isAbsoluteURL(String urlStr)
  {
    try {
      URL url = new URL(urlStr);
      return true;
    }
    catch (MalformedURLException e) {
      return false;
    }
  } 

  /**
   * Get the host portion of a URL string
   *
   * @return  URL host field
   */
  public static final String getHost(String urlStr)
    throws MalformedURLException
  {
    URL url = new URL(urlStr);
    return url.getHost();
  }

  /**
   * Get the port field of a URL string
   *
   * @return  URL port field. Returns default HTTP port (80) if the URL
   *          doesn't have a port field
   */
  public static final int getPort( String urlStr )
    throws MalformedURLException
  {
    URL url = new URL(urlStr);
    int port = url.getPort();
    if (port <= 0)
      port = DEFAULT_PORT;
    return port;
  }

  /**
   * Get the path field of a URL string
   *
   * @return  URL path field. Returns default of empty string if the URL
   *          doesn't have a path
   */
  public static final String getPath(String urlStr)
    throws MalformedURLException
  {
    URL url = new URL(urlStr);
    return url.getPath();
  }

  /**
   * Create the HTTP host:port URL substring. Convenience method for
   * building full URL's
   * 
   * @param   host     Host IP (name or number)
   * @param   port     HTTP port number
   * @return  String like "http://192.168.1.10:80"
   */
  public static final String getRequestHostURL(String host, int port)
  {
    String reqHost = "http://" + host + ":" + port;
    return reqHost;
  }
  
  /** 
   *  Convert a URL string to a relative URL string.  This is essentially
   *  the same as the URL path. If the input URL string is an absolute
   *  URL, the leading 'http:/addr:port' portion is trimmed off. If
   *  the value passed in is already a relative path, it is checked
   *  to make sure there is a leading '/', and if not, one is added.
   *
   *  TODO: check to make sure this routine is really needed 
   *
   *  @param urlStr       Input URL (relative or absolute)
   *  @param withParm     Include trailing query parameters in relative URL
   *
   */
  public static final String toRelativeURL(String urlStr, boolean withParam)
    throws MalformedURLException
  {
    String uri = urlStr;

    if (isAbsoluteURL(urlStr) == false) {
      if (urlStr.length() > 0 && urlStr.charAt(0) != '/') 
        uri = "/" + urlStr;
    }
    else {
      URL url = new URL(urlStr);
      uri = url.getPath();
      if (withParam == true) {
        String queryStr = url.getQuery();
        if (!queryStr.equals("")) {
          uri += "?" + queryStr;
        }
      }
      if (uri.endsWith("/"))
        uri = uri.substring(0,uri.length()-1);
    }
    return uri;
  }
  
  public static final String toRelativeURL(String urlStr)
    throws MalformedURLException
  {
    return toRelativeURL(urlStr, true);
  }
    
  public static final String getAbsoluteURL(String baseURLStr,
                                            String relURlStr)
    throws MalformedURLException
  {
    URL baseURL = new URL(baseURLStr);
    String url = 
      baseURL.getProtocol() + "://" +
      baseURL.getHost() + ":" +
      baseURL.getPort() +
      toRelativeURL(relURlStr);
    return url;
  }
}

